/**
 * 自定义装饰器
 */
import { SetMetadata } from '@nestjs/common';
import {
  registerDecorator,
  ValidationOptions,
  ValidationArguments,
} from 'class-validator';
import { Types } from 'mongoose';

/**
 * jwt不需要校验所使用装饰器
 */
export const JwtNoVerify = () => SetMetadata('JWT-NOT-VERIFY', true);

/**
 * 入参校验  是否为ObjectId
 */
export function IsObjectId(
  property?: string,
  validationOptions?: ValidationOptions,
) {
  return function (object: unknown, propertyName: string) {
    registerDecorator({
      name: propertyName,
      target: object.constructor,
      propertyName: propertyName,
      constraints: [property],
      options: {
        message:
          validationOptions?.message || `${propertyName} must be a ObjectId`,
        each: validationOptions?.each || false,
        groups: validationOptions?.groups || [],
        always: validationOptions?.always || true,
        context: validationOptions?.context || '',
      },
      validator: {
        validate(value: string, args: ValidationArguments) {
          try {
            return String(new Types.ObjectId(value)) === value;
          } catch (e) {
            console.log(args);
            return false;
          }
        },
      },
    });
  };
}
/**
 * 入参校验  是否为ObjectId数组
 */
export function IsObjectIdArray(
  property?: string,
  validationOptions?: ValidationOptions,
) {
  return function (object: unknown, propertyName: string) {
    registerDecorator({
      name: propertyName,
      target: object.constructor,
      propertyName: propertyName,
      constraints: [property],
      options: {
        message:
          validationOptions?.message || `${propertyName} must be a ObjectId`,
        each: validationOptions?.each || false,
        groups: validationOptions?.groups || [],
        always: validationOptions?.always || true,
        context: validationOptions?.context || '',
      },
      validator: {
        // validate(value: string[], args: ValidationArguments) {
        validate(value: string[]) {
          try {
            if (Array.isArray(value)) {
              return (
                value.filter((e) => String(new Types.ObjectId(e)) === e)
                  .length > 0
              );
            } else {
              return false;
            }
          } catch (e) {
            return false;
          }
        },
      },
    });
  };
}

/**
 * 角色装饰器 使用方法 @Role
 * ("2022")
 */
export const Role = (...roles: string[]) => SetMetadata('roles', roles);
